from flask import Blueprint, jsonify, request
from models.sessions import Sessions, Conversations, EventType, ReviewType
from datetime import datetime, timedelta
from models import db

session_bp = Blueprint('session', __name__)

@session_bp.route('/sessions', methods=['GET'])
def get_sessions():
    """
    获取会话列表
    tags:
        session
    description:
        获取会话列表，支持按用户ID和时间段过滤
    Parameters:
        user_id (int, optional): 用户ID
        start_date (str, optional): 开始日期 (YYYY-MM-DD)
        end_date (str, optional): 结束日期 (YYYY-MM-DD)
        
    Returns:
        JSON: 会话列表
    """
    try:
        query = Sessions.query

        # 用户ID过滤
        user_id = request.args.get('user_id')
        if user_id:
            query = query.filter(Sessions.user_id == user_id)

        # 时间段过滤
        start_date = request.args.get('start_date')
        end_date = request.args.get('end_date')
        
        if start_date:
            start_datetime = datetime.strptime(start_date, '%Y-%m-%d')
            query = query.filter(Sessions.start_time >= start_datetime)
        
        if end_date:
            end_datetime = datetime.strptime(end_date, '%Y-%m-%d')
            query = query.filter(Sessions.start_time <= end_datetime)

        sessions = query.all()
        return jsonify([{
            'session_id': s.session_id,
            'user_id': s.user_id,
            'event_type': s.event_type.value,
            'initial_query': s.initial_query,
            'is_active': s.is_active,
            'start_time': s.start_time.isoformat(),
            'end_time': s.end_time.isoformat() if s.end_time else None
        } for s in sessions])

    except Exception as e:
        return jsonify({'error': str(e)}), 400

@session_bp.route('/sessions/<session_id>/conversations', methods=['GET'])
def get_conversations(session_id):
    """
    获取会话下的对话记录
    tags:
        session

    description: 
        获取指定会话ID下的对话记录列表，按时间排序
    Args:
        session_id (str): 会话ID
        
    Returns:
        JSON: 对话记录列表（按时间排序）
    """
    try:
        conversations = Conversations.query\
            .filter_by(session_id=session_id)\
            .order_by(Conversations.create_time)\
            .all()
            
        return jsonify([{
            'conversation_id': c.conversation_id,
            'user_query': c.user_query,
            'response': c.response,
            'key_info': c.key_info,
            'review': c.review.value if c.review else None,
            'create_time': c.create_time.isoformat()
        } for c in conversations])

    except Exception as e:
        return jsonify({'error': str(e)}), 400


@session_bp.route('/conversations/<conversation_id>/review', methods=['PUT'])
def update_review(conversation_id):
    """
    更新对话评价
    description: 更新指定对话的评价类型
    Args:
        conversation_id (str): 对话ID

    JSON Body:
        review (str): 评价类型 ('like' or 'dislike')
        
    Returns:
        JSON: 更新结果
    """
    try:
        review = request.json.get('review')
        if not review or review not in ['like', 'dislike']:
            return jsonify({'error': 'Invalid review value'}), 400

        conversation = Conversations.query.get(conversation_id)
        if not conversation:
            return jsonify({'error': 'Conversation not found'}), 404

        conversation.review = review
        db.session.commit()
        
        return jsonify({'message': 'Review updated successfully'})

    except Exception as e:
        return jsonify({'error': str(e)}), 400
    
@session_bp.route('/sessions', methods=['DELETE'])
def delete_sessions():
    """
    删除一个或多个会话及其对应的对话记录
    tags:
        session
    description:
        支持删除单个或多个 session_id 的会话及其对应的对话记录
    Parameters (JSON body):
        session_ids (list or str): 单个 session_id 字符串，或 session_id 列表
    Returns:
        JSON: 删除结果
    """
    try:
        data = request.get_json()
        session_ids = data.get('session_ids')

        # 标准化为列表
        if isinstance(session_ids, str):
            session_ids = [session_ids]
        elif not isinstance(session_ids, list) or not session_ids:
            return jsonify({'error': '参数 session_ids 必须为非空字符串或列表'}), 400

        # 删除对话记录
        deleted_conversations = Conversations.query.filter(
            Conversations.session_id.in_(session_ids)
        ).delete(synchronize_session=False)

        # 删除会话记录
        deleted_sessions = Sessions.query.filter(
            Sessions.session_id.in_(session_ids)
        ).delete(synchronize_session=False)

        db.session.commit()

        return jsonify({
            'deleted_sessions': deleted_sessions,
            'deleted_conversations': deleted_conversations
        })

    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500
    
@session_bp.route('/conversations', methods=['DELETE'])
def delete_conversations():
    """
    删除一个或多个对话记录，若对应 session 无剩余对话记录，则自动删除 session。
    tags:
        session

    description:
        根据传入的 conversation_id（字符串或列表）删除对应的对话记录
        删除后检查所属 session，若该 session 已无对话记录，则一并删除。

    Parameters (JSON body):
        - conversation_ids (str or list): 要删除的 conversation_id 或多个 ID 列表

    Returns:
        JSON: 删除的记录数量和被删除的 session_id 列表
    """
    try:
        data = request.get_json()
        conversation_ids = data.get('conversation_ids')

        # 参数校验与标准化
        if isinstance(conversation_ids, str):
            conversation_ids = [conversation_ids]
        elif not isinstance(conversation_ids, list) or not conversation_ids:
            return jsonify({'error': '参数 conversation_ids 必须为非空字符串或列表'}), 400
        
        # 查询这些对话对应的 session_id
        sessions_to_check = db.session.query(Conversations.session_id)\
            .filter(Conversations.conversation_id.in_(conversation_ids))\
            .distinct()\
            .all()
        sessions_to_check = [s[0] for s in sessions_to_check]

        # 删除操作
        deleted_count = Conversations.query.filter(
            Conversations.conversation_id.in_(conversation_ids)
        ).delete(synchronize_session=False)
        # 删除空的 session
        deleted_sessions = []
        for session_id in sessions_to_check:
            remaining = db.session.query(Conversations).filter_by(session_id=session_id).count()
            if remaining == 0:
                db.session.query(Sessions).filter_by(session_id=session_id).delete()
                deleted_sessions.append(session_id)
        db.session.commit()

        return jsonify({
            'deleted_conversations': deleted_count,
            'deleted_sessions': deleted_sessions
        })

    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

@session_bp.route('/conversations/all', methods=['GET'])
def get_all_conversations():
    """
    查询所有对话记录，可按 user_query、response、key_info、event_type 模糊查询，支持分页。
    tags:
        conversation

    query 参数:
        - user_query (str, optional): 问题内容模糊查询
        - response (str, optional): 回复内容模糊查询
        - key_info (str, optional): 关键信息模糊查询
        - event_type (str, optional): 事件类型精确查询（枚举值）
        - review (str, optional): 点赞或点踩（like / dislike）
        - user_id (int, optional): 用户 ID 精确查询
        - page (int, optional): 页码（默认 1）
        - page_size (int, optional): 每页条数（默认 10）

    Returns:
        JSON: 分页后的对话列表及总数
    """
    try:
        user_query = request.args.get('user_query')
        response_text = request.args.get('response')
        key_info = request.args.get('key_info')
        event_type = request.args.get('event_type')
        review = request.args.get('review')
        user_id = request.args.get('user_id')
        page = int(request.args.get('page', 1))
        page_size = int(request.args.get('page_size', 10))

        query = db.session.query(Conversations, Sessions).join(
            Sessions, Conversations.session_id == Sessions.session_id
        )

        # 动态添加过滤条件
        if user_query:
            query = query.filter(Conversations.user_query.ilike(f'%{user_query}%'))
        if response_text:
            query = query.filter(Conversations.response.ilike(f'%{response_text}%'))
        if key_info:
            query = query.filter(Conversations.key_info.ilike(f'%{key_info}%'))
        if review == 'null':
            query = query.filter(Conversations.review.is_(None))
        elif review is not None:
            try:
                enum_review = ReviewType(review)
                query = query.filter(Conversations.review == enum_review)
            except ValueError:
                return jsonify({'error': f'无效的 review 值: {review}'}), 400

        if event_type:
            try:
                enum_event_type = EventType(event_type) 
                query = query.filter(Sessions.event_type == enum_event_type)
            except ValueError:
                return jsonify({'error': f'无效的 event_type: {event_type}'}), 400
        if user_id:
            query = query.filter(Sessions.user_id == user_id)

        total = query.count()
        results = query.order_by(Conversations.create_time.desc()) \
                       .offset((page - 1) * page_size) \
                       .limit(page_size) \
                       .all()

        return jsonify({
            'total': total,
            'page': page,
            'page_size': page_size,
            'records': [{
                'conversation_id': conv.conversation_id,
                'user_query': conv.user_query,
                'response': conv.response,
                'key_info': conv.key_info,
                'event_type': sess.event_type.value if sess.event_type else None,
                'review': conv.review.value if conv.review else None,
                'create_time': conv.create_time.isoformat(),
                'user_id': sess.user_id,
                'user_name': user_name
            } for conv, sess, user_name in results]
        })
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@session_bp.route('/sessions/cleanup', methods=['DELETE'])
def cleanup_sessions():
    """
    清理过期的会话记录和对应的对话记录。
    删除超过指定天数的会话及其对应的对话记录。
    tags:
        session
    description:
        根据用户提供的天数参数，删除指定日期之前的所有会话及其对应的对话记录。
    Parameters:
        days_to_keep (int): 要保留的天数，超过这个天数的会话及其对话记录将被删除
    Returns:
        JSON: 删除结果
    """
    try:
        # 获取传入的 days_to_keep 参数，默认为 30 天
        data = request.get_json()
        days_to_keep = int(data.get("days_to_keep", 30))

        # 计算截止日期
        cutoff_date = datetime.utcnow() - timedelta(days=days_to_keep)

        # 查找并删除过期的会话记录及其相关对话记录
        expired_sessions = Sessions.query.filter(Sessions.start_time < cutoff_date).all()
        expired_session_ids = [s.session_id for s in expired_sessions]

        if not expired_session_ids:
            return jsonify({'message': 'No sessions to delete'}), 200

        # 删除相关的对话记录
        deleted_conversations = Conversations.query.filter(
            Conversations.session_id.in_(expired_session_ids)
        ).delete(synchronize_session=False)

        # 删除过期的会话记录
        deleted_sessions = Sessions.query.filter(
            Sessions.session_id.in_(expired_session_ids)
        ).delete(synchronize_session=False)

        db.session.commit()

        return jsonify({
            'status': 'success',
            'deleted_sessions': deleted_sessions,
            'deleted_conversations': deleted_conversations
        }), 200

    except Exception as e:
        db.session.rollback()
        return jsonify({
            'status': 'error',
            'error': str(e)
        }), 500